当不能推导函数模板参数时，可以在函数模板名称后面显式地指定。例如:

\begin{lstlisting}[style=styleCXX]
template<typename T> T default_value()
{
	return T{};
}

int main()
{
	return default_value<int>();
}
\end{lstlisting}

对于可推导的模板参数也可以这样做:

\begin{lstlisting}[style=styleCXX]
template<typename T> void compute(T p)
{
	...
}

int main()
{
	compute<double>(2);
}
\end{lstlisting}

当显式指定了模板参数，对应参数就不再需要推导了。这允许对函数调用参数进行转换，而这不能在推导式调用中进行。上面的例子中，compute<double>(2)调用中的参数2将隐式转换为double。

可以显式地指定一些模板参数，同时推导出其他参数。但显式指定的参数总是与模板参数从左到右匹配。因此，应该首先指定不能推导(或显式指定)的参数。例如:

\begin{lstlisting}[style=styleCXX]
template<typename Out, typename In>
Out convert(In p)
{
	...
}

int main() {
	auto x = convert<double>(42); // the type of parameter p is deduced,
	// but the return type is explicitly specified
}
\end{lstlisting}

有时，可以指定空模板参数列表，以确保所选函数是一个模板实例，同时可以使用推导来确定模板参数:

\begin{lstlisting}[style=styleCXX]
int f(int); // #1
template<typename T> T f(T); // #2
int main() {
	auto x = f(42); // calls #1
	auto y = f<>(42); // calls #2
}
\end{lstlisting}

f(42)选择非模板函数，因为重载解析在其他条件都相同的情况下更匹配普通函数。但对于f<>(42)，因模板参数列表的存在，排除了非模板函数(即使没有指定实际的模板参数)。

友元函数声明的上下文中，显式模板参数列表存在一个有趣的效果。看看下面的例子:

\begin{lstlisting}[style=styleCXX]
void f();
template<typename> void f();
namespace N {
	class C {
		friend int f(); // OK
		friend int f<>(); // ERROR: return type conflict
	};
}
\end{lstlisting}

使用普通标识符命名友元函数时，该函数只会在最近的封闭范围内查找。若找不到，则会在该范围内声明一个新实体(但仍然是“不可见”的，除非通过参数依赖查找(ADL);参见第13.2.2节)。这就是上面第一个友元声明所发生的情况:没有f在名称空间N中声明，所以新的N::f()是“不可见”的声明。

但为友元命名的标识符后面跟着模板参数列表时，此时模板必须通过常规查找可见，而常规查找将向可能需要的任意数量的作用域扩展。因此，上面的第二个声明会找到全局函数模板f()，因为返回类型不匹配(这里没有执行ADL，由前面友元函数声明创建的声明会忽略)，所以是编译器会报错。

使用SFINAE原则替换显式指定的模板参数:若替换在即时上下文中导致错误，则丢弃函数模板，但其他模板仍可能成功。例如:

\begin{lstlisting}[style=styleCXX]
template<typename T> typename T::EType f(); // #1
template<typename T> T f(); // #2

int main() {
	auto x = f<int*>();
}
\end{lstlisting}

将int*替换为候选\#1中的T导致替换失败，但在候选\#2中成功了，因此这就是选中的候选。若在替换后只剩下一个候选函数，那么带有显式模板参数的函数模板行为与普通函数非常相似，包括在许多上下文中衰变为指向函数类型的指针。也就是说，将上面的main()替换为

\begin{lstlisting}[style=styleCXX]
int main() {
	auto x = f<int*>; // OK: x is a pointer to function
}
\end{lstlisting}

生成一个有效的翻译单元。然而，下面的例子

\begin{lstlisting}[style=styleCXX]
template<typename T> void f(T);
template<typename T> void f(T, T);

int main() {
	auto x = f<int*>; // ERROR: there are two possible f<int*> here
}
\end{lstlisting}

无效，因为f<int*>在这种情况下没有标识单个函数。

可变参数函数模板也可以与显式的模板参数一起使用:

\begin{lstlisting}[style=styleCXX]
template<typename ... Ts> void f(Ts ... ps);

int main() {
	f<double, double, int>(1, 2, 3); // OK: 1 and 2 are converted to double
}
\end{lstlisting}

有趣的是，参数包可以部分显式地指定和推导:

\begin{lstlisting}[style=styleCXX]
template<typename ... Ts> void f(Ts ... ps);

int main() {
	f<double, int>(1, 2, 3); // OK: the template arguments are <double, int, int>
}
\end{lstlisting}









